const { Liquid, Tokenizer, Hash, Context } = require('liquidjs');
const { parseFilePath, devPath, renderFilePath, fsExistsSync } = require('../util');
const { __assign } = require('tslib');
const fs = require('fs');
const { theme } = require('../config');

exports.template = {
  parseFilePath,
  renderFilePath,
  parse: function (token, remainTokens) {
    const args = token.args;
    const tokenizer = new Tokenizer(args, this.liquid.options.operatorsTrie);
    if (tokenizer.input) {
      tokenizer.input = tokenizer.input.replace(/[\{|\}]/g, '');

      this['file'] = this.parseFilePath(tokenizer, this.liquid);
      this['currentFile'] = token.file;
    } else {
    }
    this.hash = new Hash(tokenizer.remaining());
  },
  render: function* (ctx, emitter) {
    const { liquid, hash } = this;
    const filepath = yield this.renderFilePath(this['file'], ctx, liquid);
    const childCtx = new Context({}, ctx.opts, { sync: ctx.sync, globals: ctx.globals, strictVariables: ctx.strictVariables });
    const scope = childCtx.bottom();
    __assign(scope, yield hash.render(ctx));
    // if (filepath === "node") {
    //     const templates = yield liquid._parsePartialFile("templates/" + scope.path, childCtx, this["currentFile"]);
    //     yield liquid.renderer.renderTemplates(templates, childCtx, emitter); // liquid.renderFile(templates, childCtx);
    // } else {
    //     const templates = yield liquid._parsePartialFile("templates/" + filepath, childCtx, this["currentFile"]);
    //     yield liquid.renderer.renderTemplates(templates, childCtx, emitter);
    // }
    if (!filepath) {
      const file = this.file ? this.file.propertyName : ctx.globals.templates;
      const templates = yield liquid._parsePartialFile(devPath(`/templates/${file}.liquid`), childCtx, this['currentFile']);
      yield liquid.renderer.renderTemplates(templates, childCtx, emitter);
    } else {
      if (fsExistsSync(devPath(`/sections/${filepath}.liquid`))) {
        const templates = yield liquid._parsePartialFile(devPath(`/templates/${filepath}.liquid`), childCtx, this['currentFile']);
        yield liquid.renderer.renderTemplates(templates, childCtx, emitter);
      } else {
        return '';
      }
    }
  },
};

exports.section = {
  parseFilePath,
  renderFilePath,
  parse: function (token, remainTokens) {
    const args = token.args;
    const tokenizer = new Tokenizer(args, this.liquid.options.operatorsTrie);
    tokenizer.input = tokenizer.input.replace(/[\{|\}]/g, '');
    this['file'] = this.parseFilePath(tokenizer, this.liquid);
    this['currentFile'] = token.file;
    this.hash = new Hash(tokenizer.remaining());
  },
  render: function* (ctx, emitter) {
    const { liquid, hash } = this;
    const filepath = yield this.renderFilePath(this['file'], ctx, liquid);
    const childCtx = new Context({}, ctx.opts, { sync: ctx.sync, globals: ctx.globals, strictVariables: ctx.strictVariables });
    let scope = childCtx.bottom();

    if (['header','footer'].includes(filepath) && !theme.getTemplateId()) {
      var content = fs.readFileSync(devPath(`/sections/${filepath}.liquid`), 'utf-8');
      const schemaRegExpStr = /{% schema %}([\s\S]*?){% endschema %}/g;
      const schemBody = content.match(schemaRegExpStr);
      if (schemBody) {
        content = JSON.parse(schemBody[0].replace(/({% schema %})|({% endschema %})/g, ''));
      }
      content.default['type'] = filepath;
      scope['section'] = content.default;
    }
    __assign(scope, yield hash.render(ctx));

    if (!filepath) {
      if (this.file.propertyName === 'section_name') {
        const templates = yield liquid._parsePartialFile(devPath(`/sections/${scope.section_name}.liquid`), childCtx, this['currentFile']);
        yield liquid.renderer.renderTemplates(templates, childCtx, emitter);
      } else {
        const templates = yield liquid._parsePartialFile(devPath(`/sections/${this.file.propertyName}.liquid`), childCtx, this['currentFile']);
        yield liquid.renderer.renderTemplates(templates, childCtx, emitter);
      }
    } else {
      if (fsExistsSync(devPath(`/sections/${filepath}.liquid`))) {
        const templates = yield liquid._parsePartialFile(devPath(`/sections/${filepath}.liquid`), childCtx, this['currentFile']);
        yield liquid.renderer.renderTemplates(templates, childCtx, emitter);
      } else {
        return '';
      }
    }
  },
};

exports.include = {
  parseFilePath,
  renderFilePath,
  parse: function (token, remainTokens) {
    const tokenizer = new Tokenizer(token.args, this.liquid.options.operatorsTrie);
    tokenizer.input = tokenizer.input.replace(/[\{|\}]/g, '');
    this['file'] = this.parseFilePath(tokenizer, this.liquid);
    this['currentFile'] = token.file;
    this.hash = new Hash(tokenizer.remaining());
  },
  render: function* (ctx, emitter) {
    const { liquid, hash } = this;
    const filepath = yield this.renderFilePath(this['file'], ctx, liquid);
    const childCtx = new Context({}, ctx.opts, { sync: ctx.sync, globals: ctx.globals, strictVariables: ctx.strictVariables });
    const scope = childCtx.bottom();
    __assign(scope, yield hash.render(ctx));
    if (!filepath) {
      const templates = yield liquid._parsePartialFile(devPath(`/snippets/${this.file.propertyName}.liquid`,ctx.environments.theme), childCtx, this['currentFile']);
      yield liquid.renderer.renderTemplates(templates, childCtx, emitter); // liquid.renderFile(templates, childCtx);
    } else {
      if (fsExistsSync(devPath(`/snippets/${filepath}.liquid`,ctx.environments.theme))) {
        const templates = yield liquid._parsePartialFile(devPath(`/snippets/${filepath}.liquid`,ctx.environments.theme), childCtx, this['currentFile']);
        yield liquid.renderer.renderTemplates(templates, childCtx, emitter);
      } else {
        return '';
      }
    }
  },
};

exports.system_include = {
  parseFilePath,
  renderFilePath,
  parse: function (token, remainTokens) {
    const tokenizer = new Tokenizer(token.args, this.liquid.options.operatorsTrie);
    tokenizer.input = tokenizer.input.replace(/[\{|\}]/g, '');
    this['file'] = this.parseFilePath(tokenizer, this.liquid);
    this['currentFile'] = token.file;
    this.hash = new Hash(tokenizer.remaining());
  },
  render: function* (ctx, emitter) {
    const { liquid, hash } = this;
    const filepath = yield this.renderFilePath(this['file'], ctx, liquid);
    const childCtx = new Context({}, ctx.opts, { sync: ctx.sync, globals: ctx.globals, strictVariables: ctx.strictVariables });
    const scope = childCtx.bottom();
    __assign(scope, yield hash.render(ctx));
    if (!filepath) {
      const templates = yield liquid._parsePartialFile(devPath(`/snippets/${this.file.propertyName}.liquid`), childCtx, this['currentFile']);
      yield liquid.renderer.renderTemplates(templates, childCtx, emitter); // liquid.renderFile(templates, childCtx);
    } else {
      if (fsExistsSync(devPath(`/snippets/${filepath}.liquid`))) {
        const templates = yield liquid._parsePartialFile(devPath(`/snippets/${filepath}.liquid`), childCtx, this['currentFile']);
        yield liquid.renderer.renderTemplates(templates, childCtx, emitter);
      } else {
        return '';
      }
    }
  },
};
